define(['underscore', "three", "OrbitControls", "DRACOLoader", "GLTFLoader"], (_, THREE) ->
  class Scene
    constructor: (dom) -> (
      @height = dom.clientHeight
      @width = dom.clientWidth
      @status = false
      @initCamera()
      @initScene()
      @initLight()
      @initRender()
      dom.appendChild(@renderer.domElement)
      
      @loadTestModel()
      
      @render()
    )

    initCamera: () -> (
      @camera = new THREE.PerspectiveCamera(45, @width / @height, 10, 100000)
      @camera.position.set(15.69, 3.14, 9.61)
      @camera.rotation.set(-1.5707963267948943, 1.373400766945015, 1.5707963267948943)
      @controls = new THREE.OrbitControls(@camera);
      @controls.maxPolarAngle = Math.PI * 0.5;
      @controls.minDistance = 10;
      @controls.maxDistance = 3000;
      @controls.target.set(0, 0, 0);
      @controls.autoRotate = false;
      @controls.autoRotateSpeed = 2
    )

    initScene: () -> (
      @scene = new THREE.Scene()
      r = "static/asset/textures/sky4/";
      urls = [r + "posX.jpg", r + "negX.jpg", r + "posY.jpg", r + "negY.jpg", r + "posZ.jpg", r + "negZ.jpg"];
      skytexture = new THREE.CubeTextureLoader().load(urls);
      @scene.background = skytexture;
    )

    initLight: () -> (
      hemiLight = new THREE.HemisphereLight(0xc38e50, 0x111111, 0.1);
      hemiLight.position.set(0, 500, 0)
      @scene.add(hemiLight)
      
      @pointLight = new THREE.PointLight(0xffffff, 0.5)
      @scene.add(@pointLight)
      
      @sunLight = new THREE.DirectionalLight(0xc38e50, 2.0);
      @sunLight.position.set(-1000, 500, -1000);
      @sunLight.castShadow = true;
      
      @sunLight.shadow.mapSize.width = 1024;
      @sunLight.shadow.mapSize.height = 1024;
      @sunLight.shadow.camera.near = 10;
      @sunLight.shadow.camera.far = 10000;
      @sunLight.shadow.bias= -0.001;

      @sunLight.shadow.camera.left = -900;
      @sunLight.shadow.camera.right = 900;
      @sunLight.shadow.camera.top = 900;
      @sunLight.shadow.camera.bottom = -900;
      @scene.add(@sunLight);
    )

    initRender: () -> (
      @renderer = new THREE.WebGLRenderer({ antialias: true })
      @renderer.setSize(@width, @height);
      @renderer.setPixelRatio(window.devicePixelRatio);
      @renderer.shadowMap.enabled = true;
      @renderer.shadowMap.type = THREE.PCFSoftShadowMap;
      @renderer.gammaInput= true;
      @renderer.gammaOutput = true;
    )

    loadTestModel: () -> (
      console.log(performance.now())
      gltfLoader = new THREE.GLTFLoader()
      dracoLoader = new THREE.DRACOLoader()
      dracoLoader.setDecoderPath("static/test/");
      dracoLoader.setDecoderConfig({ type: "js" });

      gltfLoader.setDRACOLoader(dracoLoader)

      gltfLoader.load("static/test/modelDraco.gltf", (gltf) => (
        grounds = new THREE.Group()
        console.log(gltf.scene.children)
        _.each(gltf.scene.children, (child) =>
          if child
            console.log(child)
            grounds.add(child)
        )
        console.log(performance.now())
        @scene.add(grounds)
      ))
    )

    render: () -> (
      window.requestAnimationFrame(@render.bind(@))
      @pointLight.position.copy(@camera.position)
      @pointLight.scale.copy(@camera.scale)
      @controls.update()
      @renderer.render(@scene, @camera)
    )

  return Scene
)